const dayjs = require('dayjs');
const qpay = require('../services/qpay');
const logger = require('../config/logger');
const crypto = require('crypto');
const url = require('url');

// 验证和清理URL
function sanitizeCallbackUrl(baseUrl) {
  try {
    const parsedUrl = new URL(baseUrl);
    if (!['http:', 'https:'].includes(parsedUrl.protocol)) {
      throw new Error('不支持的URL协议');
    }
    parsedUrl.username = '';
    parsedUrl.password = '';
    if (!parsedUrl.pathname.startsWith('/')) {
      parsedUrl.pathname = '/' + parsedUrl.pathname;
    }
    parsedUrl.pathname = parsedUrl.pathname.replace(/[^a-zA-Z0-9-_/]/g, '');
    return parsedUrl.toString();
  } catch (error) {
    logger.error('回调URL验证失败', { baseUrl, error: error.message });
    throw new Error('无效的回调URL');
  }
}

async function createOrder(request, reply) {
  const { 
    userId, 
    storeId, 
    seatId, 
    bookingMethod, 
    paymentMethod,
    orderStartTime, 
    orderEndTime,
    totalAmount,
    balanceDeduction,
    voucherDiscount,
    actualAmount
  } = request.body;

  try {
    // 检查用户认证状态
    if (!request.user || !request.user.id) {
      logger.error('创建订单失败：用户未认证', { request: request.body });
      return reply.code(401).send({ error: '请先登录' });
    }

    // 检查用户是否存在
    const user = await this.prisma.user.findUnique({
      where: { id: request.user.id }
    });

    if (!user) {
      logger.error('创建订单失败：用户不存在', { userId: request.user.id });
      return reply.code(404).send({ error: '用户不存在' });
    }

    // 检查座位是否可用
    if (seatId) {
      const existingReservation = await this.prisma.reservationLog.findFirst({
        where: {
          seatId,
          OR: [
            {
              AND: [
                { startTime: { lte: new Date(orderStartTime) } },
                { endTime: { gt: new Date(orderStartTime) } }
              ]
            },
            {
              AND: [
                { startTime: { lt: new Date(orderEndTime) } },
                { endTime: { gte: new Date(orderEndTime) } }
              ]
            }
          ]
        }
      });

      if (existingReservation) {
        return reply.code(400).send({ error: '该时段座位已被预约' });
      }
    }

    // 创建订单
    const order = await this.prisma.order.create({
      data: {
        userId: request.user.id,
        storeId,
        seatId,
        bookingMethod,
        paymentMethod,
        status: '待付款',
        orderStartTime: new Date(orderStartTime),
        orderEndTime: new Date(orderEndTime),
        totalAmount,
        balanceDeduction,
        voucherDiscount,
        actualAmount
      }
    });

    // 如果有座位，创建预约记录
    if (seatId) {
      await this.prisma.reservationLog.create({
        data: {
          userId: request.user.id,
          orderId: order.id,
          seatId,
          startTime: new Date(orderStartTime),
          endTime: new Date(orderEndTime)
        }
      });
    }

    // 如果使用余额支付
    if (paymentMethod === '余额') {
      if (user.balance < actualAmount) {
        return reply.code(400).send({ error: '余额不足' });
      }

      // 使用事务处理支付
      await this.prisma.$transaction(async (prisma) => {
        // 更新用户余额
        await prisma.user.update({
          where: { id: user.id },
          data: {
            balance: {
              decrement: actualAmount
            }
          }
        });

        // 创建支付记录
        await prisma.payment.create({
          data: {
            orderId: order.id,
            amount: actualAmount,
            paymentMethod: '余额',
            paymentStatus: '已支付',
            paymentTime: new Date()
          }
        });

        // 更新订单状态
        await prisma.order.update({
          where: { id: order.id },
          data: {
            status: '待使用'
          }
        });

        // 创建对账记录
        await prisma.reconciliation.create({
          data: {
            orderId: order.id,
            type: '订单收入',
            amount: actualAmount,
            createdAt: new Date()
          }
        });
      });

      return reply.code(201).send({
        ...order,
        status: '待使用'
      });
    }

    // 如果使用QPay支付
    if (paymentMethod === 'qpay') {
      // 生成安全的时间戳和签名
      const timestamp = Date.now();
      const nonce = crypto.randomBytes(16).toString('hex');
      const signature = crypto
        .createHmac('sha256', process.env.QPAY_SECRET_KEY)
        .update(`${timestamp}${nonce}`)
        .digest('hex');

      // 构造安全的回调URL
      const baseCallbackUrl = sanitizeCallbackUrl(process.env.BASE_URL);
      const callbackUrl = new URL('/orders/callback', baseCallbackUrl);
      
      // 添加安全参数
      callbackUrl.searchParams.append('timestamp', timestamp);
      callbackUrl.searchParams.append('nonce', nonce);
      callbackUrl.searchParams.append('signature', signature);
      callbackUrl.searchParams.append('orderId', order.id);

      // 调用QPay创建发票
      const qpayResult = await qpay.createInvoice({
        invoice_code: process.env.QPAY_INVOICE_CODE,
        sender_invoice_no: `O${order.id}`,
        invoice_receiver_code: "terminal",
        invoice_description: `Order ${order.id} payment`,
        amount: actualAmount,
        callback_url: callbackUrl.toString(),
        sender_branch_code: "ONLINE",
        sender_staff_code: "SYSTEM",
        invoice_receiver_data: {
          register: user.phone || "",
          name: user.name || "",
          email: user.email || "",
          phone: user.phone || ""
        }
      });

      // 更新订单，添加QPay发票信息
      const updatedOrder = await this.prisma.order.update({
        where: { id: order.id },
        data: {
          qpayInvoiceId: qpayResult.invoice_id,
          qpayQrText: qpayResult.qr_text,
          qpayQrImage: qpayResult.qr_image,
          qpayPaymentUrl: qpayResult.qPay_shortUrl
        }
      });

      return reply.code(201).send({
        ...updatedOrder,
        qrText: qpayResult.qr_text,
        qrImage: qpayResult.qr_image,
        paymentUrl: qpayResult.qPay_shortUrl,
        urls: qpayResult.urls
      });
    }

    return reply.code(201).send(order);
  } catch (error) {
    logger.error('创建订单失败', {
      error: error.message,
      stack: error.stack,
      userId: request.user?.id,
      request: request.body
    });
    return reply.code(500).send({ error: '创建订单失败' });
  }
}

// 验证QPay回调签名
function verifyQPayCallbackSignature(request, expectedSignature) {
  const { timestamp, nonce } = request.query;
  
  if (!timestamp || !nonce || !expectedSignature) {
    logger.error('签名验证失败：缺少必要参数', { query: request.query, ip: request.ip });
    return false;
  }

  const now = Date.now();
  if (Math.abs(now - parseInt(timestamp)) > 300000) {
    logger.error('签名验证失败：时间戳过期', { timestamp, ip: request.ip });
    return false;
  }

  const signString = `${timestamp}${nonce}`;
  const calculatedSignature = crypto
    .createHmac('sha256', process.env.QPAY_SECRET_KEY)
    .update(signString)
    .digest('hex');

  return crypto.timingSafeEqual(
    Buffer.from(expectedSignature),
    Buffer.from(calculatedSignature)
  );
}

async function handleOrderCallback(request, reply) {
  const { orderId, timestamp, nonce, signature } = request.query;

  if (!verifyQPayCallbackSignature(request, signature)) {
    logger.error('订单回调处理失败：签名验证未通过', { query: request.query, ip: request.ip });
    return reply.code(401).send('签名验证失败');
  }

  try {
    const order = await this.prisma.order.findUnique({
      where: { 
        id: parseInt(orderId, 10)
      }
    });

    if (!order) {
      logger.error('订单回调处理失败：未找到订单', { 
        orderId,
        query: request.query,
        ip: request.ip 
      });
      return reply.code(404).send('未找到订单');
    }

    const paymentInfo = await qpay.checkPayment('INVOICE', order.qpayInvoiceId);
    
    if (!paymentInfo || !paymentInfo.rows || paymentInfo.rows.length === 0) {
      logger.error('订单回调处理失败：未找到支付记录', {
        invoice_id: order.qpayInvoiceId,
        order_id: order.id,
        payment_info: paymentInfo,
        ip: request.ip
      });
      return reply.code(200).send('支付未完成');
    }

    const latestPayment = paymentInfo.rows[0];
    if (latestPayment.payment_status !== 'PAID') {
      logger.error('订单回调处理失败：支付未完成', {
        invoice_id: order.qpayInvoiceId,
        payment_status: latestPayment.payment_status,
        ip: request.ip
      });
      return reply.code(200).send('支付未完成');
    }

    await this.prisma.$transaction(async (prisma) => {
      const existingOrder = await prisma.order.findFirst({
        where: {
          qpayInvoiceId: order.qpayInvoiceId,
          status: '待付款'
        }
      });

      if (!existingOrder) {
        logger.warn('订单回调处理：未找到对应的待付款订单或已处理', { 
          invoice_id: order.qpayInvoiceId, 
          ip: request.ip 
        });
        return;
      }

      // 更新订单状态
      await prisma.order.update({
        where: { id: existingOrder.id },
        data: {
          status: '待使用',
          updatedAt: new Date()
        }
      });

      // 创建支付记录
      await prisma.payment.create({
        data: {
          orderId: existingOrder.id,
          amount: existingOrder.actualAmount,
          paymentMethod: 'qpay',
          paymentStatus: '已支付',
          paymentTime: new Date(),
          qpayPaymentId: latestPayment.payment_id
        }
      });

      // 创建对账记录
      await prisma.reconciliation.create({
        data: {
          orderId: existingOrder.id,
          type: '订单收入',
          amount: existingOrder.actualAmount,
          createdAt: new Date()
        }
      });
    });

    // 创建电子收据
    try {
      const orderAfterUpdate = await this.prisma.order.findFirst({ 
        where: { qpayInvoiceId: order.qpayInvoiceId } 
      });
      
      if (orderAfterUpdate && orderAfterUpdate.status === '待使用' && !orderAfterUpdate.ebarimtId) {
        const ebarimtResult = await qpay.createEbarimt(latestPayment.payment_id, 'CITIZEN');
        if (ebarimtResult) {
          await this.prisma.order.update({
            where: { id: orderAfterUpdate.id },
            data: {
              ebarimtId: ebarimtResult.ebarimt_id
            }
          });
          logger.info('电子收据创建成功', { 
            payment_id: latestPayment.payment_id, 
            orderId: orderAfterUpdate.id, 
            ebarimtId: ebarimtResult.ebarimt_id, 
            ip: request.ip 
          });
        }
      }
    } catch (ebarimtError) {
      logger.error('创建电子收据失败', {
        error: ebarimtError.message,
        payment_id: latestPayment.payment_id,
        invoice_id: order.qpayInvoiceId,
        ip: request.ip
      });
    }

    logger.info('订单回调处理成功', { 
      payment_id: latestPayment.payment_id, 
      invoice_id: order.qpayInvoiceId, 
      ip: request.ip 
    });
    
    return reply.send('SUCCESS');

  } catch (error) {
    logger.error('订单回调处理失败', {
      error: error.message,
      stack: error.stack,
      query: request.query,
      ip: request.ip
    });
    return reply.code(500).send('处理失败');
  }
}

async function checkPaymentStatus(request, reply) {
  const { orderId } = request.params;

  try {
    if (!request.user || !request.user.id) {
      logger.error('查询支付状态失败：用户未认证', { orderId });
      return reply.code(401).send({ error: '请先登录' });
    }

    const order = await this.prisma.order.findFirst({
      where: { 
        id: parseInt(orderId, 10),
        userId: request.user.id
      }
    });

    if (!order) {
      logger.error('查询支付状态失败：未找到订单', { orderId });
      return reply.code(404).send({ error: '未找到订单' });
    }

    if (order.payment) {
      return reply.send({
        orderId: order.id,
        status: order.status,
        paymentId: order.payment.qpayPaymentId,
        totalAmount: order.totalAmount,
        balanceDeduction: order.balanceDeduction,
        voucherDiscount: order.voucherDiscount,
        actualAmount: order.actualAmount,
        createdAt: order.createdAt,
        updatedAt: order.updatedAt,
        qpayInvoiceId: order.qpayInvoiceId,
        qrText: order.qpayQrText,
        qrImage: order.qpayQrImage,
        paymentUrl: order.qpayPaymentUrl
      });
    }

    if (!order.qpayInvoiceId) {
      logger.error('查询支付状态失败：未找到发票ID', { orderId });
      return reply.send({
        orderId: order.id,
        status: order.status,
        totalAmount: order.totalAmount,
        balanceDeduction: order.balanceDeduction,
        voucherDiscount: order.voucherDiscount,
        actualAmount: order.actualAmount,
        createdAt: order.createdAt,
        updatedAt: order.updatedAt
      });
    }

    const paymentInfo = await qpay.checkPayment('INVOICE', order.qpayInvoiceId);
    
    if (!paymentInfo || !paymentInfo.rows || paymentInfo.rows.length === 0) {
      return reply.send({
        orderId: order.id,
        status: order.status,
        totalAmount: order.totalAmount,
        balanceDeduction: order.balanceDeduction,
        voucherDiscount: order.voucherDiscount,
        actualAmount: order.actualAmount,
        createdAt: order.createdAt,
        updatedAt: order.updatedAt
      });
    }

    const latestPayment = paymentInfo.rows[0];
    
    if (latestPayment.payment_status === 'PAID' && order.status === '待付款') {
      await this.prisma.$transaction(async (prisma) => {
        await prisma.order.update({
          where: { id: order.id },
          data: {
            status: '待使用',
            updatedAt: new Date()
          }
        });

        await prisma.payment.create({
          data: {
            orderId: order.id,
            amount: order.actualAmount,
            paymentMethod: 'qpay',
            paymentStatus: '已支付',
            paymentTime: new Date(),
            qpayPaymentId: latestPayment.payment_id
          }
        });

        await prisma.reconciliation.create({
          data: {
            orderId: order.id,
            type: '订单收入',
            amount: order.actualAmount,
            createdAt: new Date()
          }
        });
      });

      try {
        const ebarimtResult = await qpay.createEbarimt(latestPayment.payment_id, 'CITIZEN');
        if (ebarimtResult) {
          await this.prisma.order.update({
            where: { id: order.id },
            data: {
              ebarimtId: ebarimtResult.ebarimt_id
            }
          });
        }
      } catch (ebarimtError) {
        logger.error('创建电子收据失败', {
          error: ebarimtError.message,
          payment_id: latestPayment.payment_id,
          invoice_id: order.qpayInvoiceId
        });
      }
    }

    return reply.send({
      orderId: order.id,
      status: latestPayment.payment_status === 'PAID' ? '待使用' : order.status,
      paymentId: latestPayment.payment_id,
      totalAmount: order.totalAmount,
      balanceDeduction: order.balanceDeduction,
      voucherDiscount: order.voucherDiscount,
      actualAmount: order.actualAmount,
      createdAt: order.createdAt,
      updatedAt: new Date(),
      qpayInvoiceId: order.qpayInvoiceId,
      qrText: order.qpayQrText,
      qrImage: order.qpayQrImage,
      paymentUrl: order.qpayPaymentUrl
    });

  } catch (error) {
    logger.error('查询支付状态失败', {
      error: error.message,
      stack: error.stack,
      orderId
    });
    return reply.code(500).send({ error: '查询支付状态失败' });
  }
}

async function getOrders(request, reply) {
  try {
    const orders = await this.prisma.order.findMany({
      include: {
        user: {
          select: {
            name: true,
            email: true
          }
        },
        store: true,
        seat: true,
        payment: true,
        voucherUsedRecords: {
          include: {
            voucher: true
          }
        }
      },
      orderBy: {
        createdAt: 'desc'
      }
    });
    return reply.send(orders);
  } catch (error) {
    logger.error('获取订单列表失败', {
      error: error.message,
      stack: error.stack
    });
    return reply.code(500).send({ error: '获取订单列表失败' });
  }
}

async function getOrder(request, reply) {
  const { id } = request.params;
  try {
    const order = await this.prisma.order.findUnique({
      where: { id: parseInt(id) },
      include: {
        user: {
          select: {
            name: true,
            email: true
          }
        },
        store: true,
        seat: true,
        payment: true,
        voucherUsedRecords: {
          include: {
            voucher: true
          }
        }
      }
    });
    
    if (!order) {
      return reply.code(404).send({ error: '订单不存在' });
    }
    return reply.send(order);
  } catch (error) {
    logger.error('获取订单信息失败', {
      error: error.message,
      stack: error.stack,
      orderId: id
    });
    return reply.code(500).send({ error: '获取订单信息失败' });
  }
}

async function getUserOrders(request, reply) {
  const { userId } = request.params;
  try {
    const orders = await this.prisma.order.findMany({
      where: { userId: parseInt(userId) },
      include: {
        store: true,
        seat: true,
        payment: true,
        voucherUsedRecords: {
          include: {
            voucher: true
          }
        }
      },
      orderBy: {
        createdAt: 'desc'
      }
    });
    return reply.send(orders);
  } catch (error) {
    logger.error('获取用户订单列表失败', {
      error: error.message,
      stack: error.stack,
      userId
    });
    return reply.code(500).send({ error: '获取用户订单列表失败' });
  }
}

async function updateOrderStatus(request, reply) {
  const { id } = request.params;
  const { status } = request.body;
  
  try {
    const order = await this.prisma.order.update({
      where: { id: parseInt(id) },
      data: { status },
      include: {
        user: {
          select: {
            name: true,
            email: true
          }
        },
        store: true,
        seat: true,
        payment: true
      }
    });
    
    return reply.send(order);
  } catch (error) {
    if (error.code === 'P2025') {
      return reply.code(404).send({ error: '订单不存在' });
    }
    logger.error('更新订单状态失败', {
      error: error.message,
      stack: error.stack,
      orderId: id,
      status
    });
    return reply.code(500).send({ error: '更新订单状态失败' });
  }
}

async function cancelOrder(request, reply) {
  const { id } = request.params;
  try {
    const order = await this.prisma.order.findUnique({
      where: { id: parseInt(id) }
    });

    if (!order) {
      return reply.code(404).send({ error: '订单不存在' });
    }

    if (order.status === '已完成' || order.status === '已取消') {
      return reply.code(400).send({ error: '该订单状态不可取消' });
    }

    const updatedOrder = await this.prisma.order.update({
      where: { id: parseInt(id) },
      data: { status: '已取消' },
      include: {
        payment: true
      }
    });

    // 如果订单已支付，创建退款记录
    if (updatedOrder.payment && updatedOrder.payment.paymentStatus === '已支付') {
      // TODO: 处理退款逻辑
    }

    // 删除预约记录
    await this.prisma.reservationLog.deleteMany({
      where: { orderId: parseInt(id) }
    });

    return reply.send(updatedOrder);
  } catch (error) {
    logger.error('取消订单失败', {
      error: error.message,
      stack: error.stack,
      orderId: id
    });
    return reply.code(500).send({ error: '取消订单失败' });
  }
}

module.exports = {
  createOrder,
  getOrders,
  getOrder,
  updateOrderStatus,
  cancelOrder,
  getUserOrders,
  handleOrderCallback,
  checkPaymentStatus
};